/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lestr.udm.core.util;

import org.lestr.udm.core.api.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author pibonnin
 */
public class TransactionnalDataManager implements IDataManager {


    private IDataManager dataManager;


    public TransactionnalDataManager(IDataManager dataManager) {

        this.dataManager = dataManager;

    }// END Constructor


    @Override
    public ISession openSession() {

        return new Session(dataManager.openSession());

    }// END Method openSession
    
    
    public interface IUntransactionnalDataManager {


        public ISession openSession();


        public static interface ISession {


            void setData(boolean newData, String id, List<IDataType> types, InputStream value);


            List<IDataType> getDataTypes(String id);


            InputStream getDataValue(String id);


            void commit();


            void close();


        }// END Interface ISession


    }// END Class DataManager


    private static class Session implements ISession {


        private ISession session;


        private Map<String, Data> datas;


        public Session(ISession session) {

            this.session = session;
            datas = new HashMap<String, Data>();

        }// END Constructor


        @Override
        public void addData(String id) {

            datas.put(id, new Data(true));

        }// END Method addData


        @Override
        public void setDataTypes(String id,
                                 List<IDataType> types) {

            if (!datas.containsKey(id))
                datas.put(id, new Data(false));

            datas.get(id).types = types;

        }// END Method setDataTypes


        @Override
        public List<IDataType> getDataTypes(String id) {

            return datas.containsKey(id) && datas.get(id).types != null
                   ? datas.get(id).types
                   : session.getDataTypes(id);

        }// END Method getDataTypes


        @Override
        public void setDataValue(String id,
                                 InputStream value) {

            if (!datas.containsKey(id))
                datas.put(id, new Data(false));

            datas.get(id).value = value;

        }// END Method setDataValue


        @Override
        public InputStream getDataValue(String id) {

            return datas.containsKey(id) && datas.get(id).value != null
                   ? datas.get(id).value
                   : session.getDataValue(id);

        }// END Method getDataValue


        @Override
        public void commit() {

            for (String id : datas.keySet()) {

                Data data = datas.get(id);

                if (data.newData)
                    session.addData(id);

                if (data.types != null)
                    session.setDataTypes(id, data.types);

                if (data.value != null)
                    session.setDataValue(id, data.value);

            }

            datas.clear();
            session.commit();

        }// END Method commit


        @Override
        public void close() {

            datas = null;
            session.close();

        }// END Method close


    }// FIN Classe ISession


    private static class Data {


        public boolean newData;


        private List<IDataType> types;


        private InputStream value;


        public Data(boolean newData) {

            this.newData = newData;

        }// END Constructor


    }// END class Data


}// END Class DataManager
